/**
 * 讯飞语音合成（TTS）HTTP服务
 * 使用 HTTP API 直接获取音频，无需 WebSocket
 * 参考文档：https://www.xfyun.cn/doc/tts/online_tts/API.html
 */

import Sound from 'react-native-sound';
import CryptoJS from 'crypto-js';
import { IFLYTEK_APP_ID, IFLYTEK_API_KEY, IFLYTEK_API_SECRET } from '@env';

class IflytekHttpTtsService {
  constructor() {
    this.currentSound = null;
    this.apiUrl = 'https://tts-api.xfyun.cn/v2/tts';
  }

  /**
   * 生成鉴权参数
   * @returns {Object} 包含 authorization、date、host 的鉴权信息
   */
  getAuthParams() {
    const url = new URL(this.apiUrl);
    const host = url.host;
    const path = url.pathname;
    const date = new Date().toUTCString();

    // 1. 构建签名原文
    const signatureOrigin = `host: ${host}\ndate: ${date}\nPOST ${path} HTTP/1.1`;

    // 2. 使用 HMAC-SHA256 加密
    const signature = CryptoJS.HmacSHA256(signatureOrigin, IFLYTEK_API_SECRET);
    const signatureBase64 = CryptoJS.enc.Base64.stringify(signature);

    // 3. 构建 authorization 参数
    const authorizationOrigin = `api_key="${IFLYTEK_API_KEY}", algorithm="hmac-sha256", headers="host date request-line", signature="${signatureBase64}"`;
    const authorization = CryptoJS.enc.Base64.stringify(
      CryptoJS.enc.Utf8.parse(authorizationOrigin),
    );

    return {
      authorization,
      date,
      host,
    };
  }

  /**
   * 合成语音（HTTP方式）
   * @param {string} text - 要合成的文本
   * @param {Object} options - 合成参数
   * @returns {Promise<string>} base64编码的音频数据
   */
  async synthesize(text, options = {}) {
    try {
      const authParams = this.getAuthParams();

      // 构建请求参数
      const requestData = {
        common: {
          app_id: IFLYTEK_APP_ID,
        },
        business: {
          aue: 'lame', // 音频编码：lame(mp3)
          auf: 'audio/L16;rate=16000', // 音频采样率
          vcn: options.voiceName || 'xiaoyan', // 发音人
          speed: options.speed || 50, // 语速：0-100
          volume: options.volume || 80, // 音量：0-100
          pitch: options.pitch || 50, // 音高：0-100
          bgs: 0, // 背景音乐
          tte: 'UTF8', // 文本编码
        },
        data: {
          status: 2, // 数据状态：2(一次传完)
          text: CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text)),
        },
      };

      // 发送 HTTP 请求
      const response = await fetch(this.apiUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: authParams.authorization,
          Date: authParams.date,
          Host: authParams.host,
        },
        body: JSON.stringify(requestData),
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`HTTP请求失败: ${response.status} ${errorText}`);
      }

      const result = await response.json();

      // 检查返回结果
      if (result.code !== 0) {
        throw new Error(`讯飞TTS错误: ${result.message || '未知错误'}`);
      }

      // 获取音频数据
      if (!result.data || !result.data.audio) {
        throw new Error('未获取到音频数据');
      }

      return result.data.audio; // base64格式的音频
    } catch (error) {
      throw error;
    }
  }

  /**
   * 播放 base64 音频
   * @param {string} base64Audio - base64编码的音频数据
   * @returns {Promise<void>}
   */
  async playBase64Audio(base64Audio) {
    return new Promise((resolve, reject) => {
      try {
        // 将 base64 转换为 data URI
        const audioUri = `data:audio/mp3;base64,${base64Audio}`;

        // 使用 react-native-sound 播放
        this.currentSound = new Sound(audioUri, '', error => {
          if (error) {
            reject(error);
            return;
          }

          this.currentSound.play(success => {
            if (success) {
            } else {
            }

            // 释放资源
            if (this.currentSound) {
              this.currentSound.release();
              this.currentSound = null;
            }

            if (success) {
              resolve();
            } else {
              reject(new Error('播放失败'));
            }
          });
        });
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 合成并播放（一步到位）
   * @param {string} text - 要合成的文本
   * @param {Object} options - 合成参数
   */
  async speak(text, options = {}) {
    try {
      // 停止当前播放
      this.stop();

      // 合成语音
      const audioData = await this.synthesize(text, options);

      // 播放音频
      await this.playBase64Audio(audioData);
    } catch (error) {
      throw error;
    }
  }

  /**
   * 停止播放
   */
  stop() {
    return new Promise(resolve => {
      if (this.currentSound) {
        try {
          this.currentSound.stop(() => {
            if (this.currentSound) {
              this.currentSound.release();
              this.currentSound = null;
            }
            resolve();
          });
        } catch (error) {
          // 出错也要清理
          if (this.currentSound) {
            this.currentSound = null;
          }
          resolve();
        }
      } else {
        resolve();
      }
    });
  }

  /**
   * 清理资源
   */
  async cleanup() {
    await this.stop();
  }
}

export default new IflytekHttpTtsService();
